﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace Handin2_Del2
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        private Canvas mainCanvas;
        private ToggleButton buttonSwitch1;
        private ToggleButton buttonSwitch2;
        private Image imageLight;

        private Polyline topLeftLine;
        private Polyline topRightLine;
        private Polyline innerLine;
        private Polyline outerLine;
        private Polyline powerLine;

        public MainWindow()
        {
            InitializeComponent();
            Width = 800;
            Height = 400;
            Title = "MainWindow";
            ResizeMode = ResizeMode.NoResize;

            mainCanvas = new Canvas();

            
            buttonSwitch1 = SetupSwitch(175, 200);
            buttonSwitch2 = SetupSwitch(460, 200);
            imageLight = SetupLight(buttonSwitch1, buttonSwitch2, 280, 10);

            topLeftLine = SetupLines(false, true, true, 0, 120, 342, 120, 342, 100);
            topRightLine = SetupLines(false, true, true, 352, 100, 352, 120, 514, 120, 514, 200);
            innerLine = SetupLines(false, false, false, 495, 280, 495, 300, 247, 300, 247, 280);
            outerLine = SetupLines(false, false, true, 532, 280, 532, 330, 210, 330, 210, 280);
            powerLine = SetupLines(true, false, true, 229, 200, 229, 150, 0, 150);

            Content = mainCanvas;
        }

        private Style SetupStyleLine(bool _multipleSwitches, bool _invertCondition)
        {
            Style tempStyle = new Style(typeof(Polyline));
            Setter stdBrush = new Setter(Polyline.StrokeProperty, Brushes.Black);
            tempStyle.Setters.Add(stdBrush);

            MultiDataTrigger tempTrigger = new MultiDataTrigger();

            Condition cond1 = new Condition(new Binding("IsChecked") { Source = buttonSwitch1 }, _invertCondition);
            tempTrigger.Conditions.Add(cond1);

            Setter tempSetter = new Setter(Polyline.StrokeProperty, Brushes.Red);
            tempTrigger.Setters.Add(tempSetter);

            if (_multipleSwitches)
            {
                Condition cond2 = new Condition(new Binding("IsChecked") { Source = buttonSwitch2 }, !_invertCondition);
                tempTrigger.Conditions.Add(cond2);
                
                MultiDataTrigger tempTrigger2 = new MultiDataTrigger();
                Condition cond3 = new Condition(new Binding("IsChecked") { Source = buttonSwitch1 }, !_invertCondition);
                tempTrigger2.Conditions.Add(cond3);
                Condition cond4 = new Condition(new Binding("IsChecked") { Source = buttonSwitch2 }, _invertCondition);
                tempTrigger2.Conditions.Add(cond4);
                tempTrigger2.Setters.Add(tempSetter);
                tempStyle.Triggers.Add(tempTrigger2);
            }

            tempStyle.Triggers.Add(tempTrigger);

            return tempStyle;
        }

        private Polyline SetupLines(bool powerLine, bool multipleSwitchLine, bool invertCondition, double x1, double y1, double x2, double y2, double x3, double y3, double? x4 = null, double? y4 = null)
        {
            Polyline polyLine = new Polyline();

            polyLine.StrokeThickness = 4;

            PointCollection polyPointCollection = new PointCollection();

            Point point1 = new Point(x1, y1);
            polyPointCollection.Add(point1);

            Point point2 = new Point(x2, y2);
            polyPointCollection.Add(point2);

            Point point3 = new Point(x3, y3);
            polyPointCollection.Add(point3);

            if(x4.HasValue && y4.HasValue)
            {
                Point point4 = new Point(x4.Value, y4.Value);
                polyPointCollection.Add(point4);
            }
           
            polyLine.Points = polyPointCollection;
            
            if(powerLine)
                polyLine.Stroke = Brushes.Red;
            else
                polyLine.Style = SetupStyleLine(multipleSwitchLine, invertCondition);
               
            mainCanvas.Children.Add(polyLine);

            return polyLine;
        }

        private ToggleButton SetupSwitch(double _leftCoord, double _topCoord)
        {
            ToggleButton tempButtonSwitch = new ToggleButton();

            BitmapImage switchDownImg = new BitmapImage(new Uri(@"SwitchDown.bmp", UriKind.RelativeOrAbsolute));
            BitmapImage switchUpImg = new BitmapImage(new Uri(@"SwitchUp.bmp", UriKind.RelativeOrAbsolute));

            FrameworkElementFactory offSwitch = new FrameworkElementFactory(typeof(Image));
            offSwitch.SetValue(Image.SourceProperty, switchUpImg);
            offSwitch.Name = "OffSwitch";

            FrameworkElementFactory onSwitch = new FrameworkElementFactory(typeof(Image));
            onSwitch.SetValue(Image.SourceProperty, switchDownImg);
            onSwitch.SetValue(Image.VisibilityProperty, Visibility.Hidden);
            onSwitch.Name = "OnSwitch";

            FrameworkElementFactory grid1 = new FrameworkElementFactory(typeof(Grid));
            grid1.AppendChild(offSwitch);
            grid1.AppendChild(onSwitch);

            ControlTemplate tempControl = new ControlTemplate(typeof(ToggleButton));
            tempControl.VisualTree = grid1;

            Trigger tempTrigger = new Trigger();
            tempTrigger.Property = ToggleButton.IsCheckedProperty;
            tempTrigger.Value = true;

            Setter tempSetter1 = new Setter();
            tempSetter1.TargetName = "OffSwitch";
            tempSetter1.Property = Image.VisibilityProperty;
            tempSetter1.Value = Visibility.Hidden;

            Setter tempSetter2 = new Setter();
            tempSetter2.TargetName = "OnSwitch";
            tempSetter2.Property = Image.VisibilityProperty;
            tempSetter2.Value = Visibility.Visible;

            tempTrigger.Setters.Add(tempSetter1);
            tempTrigger.Setters.Add(tempSetter2);

            tempControl.Triggers.Add(tempTrigger);

            tempButtonSwitch.Template = tempControl;

            tempButtonSwitch.Height = 85;
            tempButtonSwitch.Width = 130;

            Canvas.SetLeft(tempButtonSwitch, _leftCoord);
            Canvas.SetTop(tempButtonSwitch, _topCoord);

            mainCanvas.Children.Add(tempButtonSwitch);

            return tempButtonSwitch;
        }

        private Image SetupLight(ToggleButton _sourceSwitch1, ToggleButton _sourceSwitch2, double _leftCoord, double _topCoord)
        {
            BitmapImage lightOnImg = new BitmapImage(new Uri(@"LightON.bmp", UriKind.RelativeOrAbsolute));
            BitmapImage lightOffImg = new BitmapImage(new Uri(@"LightOFF.bmp", UriKind.RelativeOrAbsolute));

            Image tempImage = new Image();
            tempImage.Height = 100;
            tempImage.Width = 130;
            tempImage.Stretch = Stretch.Uniform;

            //Create Style
            Style style = new Style(typeof(Image));

            //Add standard style
            Setter stdSetter = new Setter(Image.SourceProperty, lightOffImg);
            style.Setters.Add(stdSetter);


            //Create MultiDataTrigger (InnerLine)
            MultiDataTrigger tempTrigger1 = new MultiDataTrigger();
            Condition condInner1 = new Condition(new Binding("IsChecked") { Source = _sourceSwitch1 }, false);
            Condition condInner2 = new Condition(new Binding("IsChecked") { Source = _sourceSwitch2 }, true);
            Setter setterInner = new Setter(Image.SourceProperty, lightOnImg);

            tempTrigger1.Conditions.Add(condInner1);
            tempTrigger1.Conditions.Add(condInner2);
            tempTrigger1.Setters.Add(setterInner);

            //Create MultiDataTrigger (Outerline)
            MultiDataTrigger tempTrigger2 = new MultiDataTrigger();
            Condition condOuter1 = new Condition(new Binding("IsChecked") { Source = _sourceSwitch1 }, true);
            Condition condOuter2 = new Condition(new Binding("IsChecked") { Source = _sourceSwitch2 }, false);
            Setter setterOuter = new Setter(Image.SourceProperty, lightOnImg);

            tempTrigger2.Conditions.Add(condOuter1);
            tempTrigger2.Conditions.Add(condOuter2);
            tempTrigger2.Setters.Add(setterOuter);
            
            //Add triggers to style
            style.Triggers.Add(tempTrigger1);
            style.Triggers.Add(tempTrigger2);

            //Make style active on light bulb
            tempImage.Style = style;

            //Put it in place
            Canvas.SetLeft(tempImage, _leftCoord);
            Canvas.SetTop(tempImage, _topCoord);

            //Add it to canvas with above coords
            mainCanvas.Children.Add(tempImage);

            return tempImage;
        }
    }
}
